package com.ruoyi.purchase.service.impl;
import java.util.Date;

import java.util.ArrayList;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.base.domain.SettlementAccount;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.purchase.domain.*;
import com.ruoyi.purchase.feign.client.GoodsFeignClient;
import com.ruoyi.base.domain.Goods;
import com.ruoyi.base.domain.Inventory;

import java.math.BigDecimal;

import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.purchase.dto.PurchaseStoreDto;
import com.ruoyi.purchase.mapper.*;
import com.ruoyi.purchase.utils.OrderNoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.purchase.service.IPurchaseStoreService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入库Service业务层处理
 *
 * @author wonderland
 * @date 2023-07-17
 */
@Service
public class PurchaseStoreServiceImpl implements IPurchaseStoreService {
    @Autowired
    private PurchaseStoreMapper purchaseStoreMapper;
    @Autowired
    private PurchaseStorePayMapper purchaseStorePayMapper;

    @Autowired
    private PurchaseStoreDetailMapper purchaseStoreDetailMapper;
    @Autowired
    private PurchaseOrderDetailMapper orderDetailMapper;
    @Autowired
    private PurchaseOrderMapper orderMapper;

    @Autowired
    private GoodsFeignClient goodsFeignClient;
    /**
     * 查询入库
     *
     * @param id 入库主键
     * @return 入库
     */
    @Override
    public PurchaseStore selectPurchaseStoreById(Long id) {
        return purchaseStoreMapper.selectPurchaseStoreById(id);
    }

    /**
     * 查询入库列表
     *
     * @param purchaseStore 入库
     * @return 入库
     */
    @Override
    public List<PurchaseStore> selectPurchaseStoreList(PurchaseStore purchaseStore) {
        return purchaseStoreMapper.selectPurchaseStoreList(purchaseStore);
    }

    /**
     * 新增入库
     *
     * @param dto 入库
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPurchaseStore(PurchaseStoreDto dto) {
        String note = dto.getNote();
        Long accountId = dto.getAccountId();
        List<PurchaseOrder> orderList = dto.getOrderList();
        String adminName = dto.getAdminName();
        BigDecimal totalAmount = dto.getTotalAmount();
        BigDecimal discountAmount = dto.getDiscountAmount();
        BigDecimal depositAmount = dto.getDepositAmount();
        BigDecimal payAmount = dto.getPayAmount();
        BigDecimal debtAmount = dto.getDebtAmount();
        Long state = dto.getState();
        Long storeId = dto.getStoreId();

        // 保存入库单信息
        PurchaseStore purchaseStore = getPurchaseStore(note, accountId, orderList, adminName, totalAmount, payAmount, debtAmount, state, storeId);
        int i = purchaseStoreMapper.insertPurchaseStore(purchaseStore);
        Long id = purchaseStore.getId();

        // 保存入库单详情信息
        saveStoreDetailInfo(accountId, orderList, storeId, id);
        List<Goods> goodsList = getGoodsList(orderList);
        // 保存库存信息
        saveKuCun(goodsList);
        // 结算账户减钱
        setAccount(accountId, payAmount, depositAmount);
        // 修改采购单状态为已经入库
        updateStoreOrderState(orderList);
        // 生成付款单信息
        savePayInfo(accountId, orderList, payAmount, id);

        return i;
    }

    private void saveKuCun(List<Goods> goodsList) {
        goodsList.forEach(goods -> {
            String code = goods.getCode();
            Long number = goods.getNumber();
            Inventory inventory = goodsFeignClient.getByBarCode(code);// 根据code获取库存信息
            if (inventory != null){
                inventory.setName(goods.getName());
                inventory.setSize(goods.getSpec());
                inventory.setModel(goods.getModel());
                inventory.setColor(goods.getColor());
                inventory.setType(null);
                inventory.setUnit(goods.getUnit());
                inventory.setUnitPrice(goods.getPurchasePrice());
                // 更新库存数量和金额
                inventory.setInitialInventory(inventory.getInitialInventory() + number);
                inventory.setInventory(inventory.getInventory() + number);
                inventory.setInventoryAmount(inventory.getInventory() * inventory.getUnitPrice());
            }
            goodsFeignClient.updateInventory(inventory);
        });
    }

    private void updateStoreOrderState(List<PurchaseOrder> orderList) {
        orderList.forEach(s ->{
            s.setState(2L);
            orderMapper.updatePurchaseOrder(s);
        });
    }

    private void savePayInfo(Long accountId, List<PurchaseOrder> orderList, BigDecimal payAmount, Long id) {
        orderList.forEach(s ->{
            PurchaseStorePay purchaseStorePay = new PurchaseStorePay();
            purchaseStorePay.setStoreId(id);
            purchaseStorePay.setOrderNo(s.getReceiptNumber());
            purchaseStorePay.setAccountId(accountId);
            purchaseStorePay.setPayAmout(payAmount);
            purchaseStorePayMapper.insertPurchaseStorePay(purchaseStorePay);
        });
    }

    private void saveStoreDetailInfo(Long accountId, List<PurchaseOrder> orderList, Long storeId, Long id) {
        List<PurchaseStoreDetail> storeDetails =
                orderList.stream().map(orders -> createPurchaseStoreDetail(id, accountId, storeId, orders))
                        .collect(Collectors.toList());
        storeDetails.forEach(s -> {
                    purchaseStoreDetailMapper.insertPurchaseStoreDetail(s);
                }
        );
    }

    private void setAccount(Long accountId, BigDecimal payAmount, BigDecimal depositAmount) {
        AjaxResult ajaxResult = goodsFeignClient.getInfo(accountId);
        ObjectMapper objectMapper = new ObjectMapper();
        SettlementAccount account = objectMapper.convertValue(ajaxResult.get("data"), SettlementAccount.class);
        BigDecimal currentBalance = account.getCurrentBalance();
        if (account != null && currentBalance != null) {
            BigDecimal newBalance = currentBalance.subtract(payAmount.add(depositAmount));
            account.setCurrentBalance(newBalance);
        }
        goodsFeignClient.edit(account);
    }

    private List<Goods> getGoodsList(List<PurchaseOrder> orderList) {
        List<Long> orderIds = new ArrayList<>();
        List<Long> goodsIds = new ArrayList<>();
        List<PurchaseOrderDetail> orderDetails = new ArrayList<>();
        List<Goods> goodsList = new ArrayList<>();
        // 遍历订单列表，获取订单的ID并添加到orderIds列表中
        orderList.forEach(o -> {
            Long orderId = o.getId();
            orderIds.add(orderId);
        });
        // 遍历orderIds，根据每个orderId获取对应的购买订单明细记录，并添加到orderDetails列表中
        orderIds.forEach(orderId -> {
            List<PurchaseOrderDetail> orderDetailsByOrderId = orderDetailMapper.getOrderDetailsByOrderId(orderId); // 假设使用orderId查询对应订单明细记录的方法为getOrderDetailsByOrderId()
            orderDetails.addAll(orderDetailsByOrderId);
        });
        orderDetails.forEach(orderDetail -> {
            Long goodsId = orderDetail.getGoodsId();
            goodsIds.add(goodsId);
        });
        goodsIds.forEach(goodId ->{
            Goods goods = goodsFeignClient.getGoodsById(Long.valueOf(goodId));
            goodsList.add(goods);
        });
        return goodsList;
    }



    private PurchaseStoreDetail createPurchaseStoreDetail(Long id, Long accountId, Long storeId, PurchaseOrder orders) {
        PurchaseStoreDetail storeDetail = new PurchaseStoreDetail();
        storeDetail.setStoreId(id);
        storeDetail.setAccountId(accountId);
        storeDetail.setStorageId(storeId);
        storeDetail.setOrderId(orders.getId());
        return storeDetail;
    }

    private static PurchaseStore getPurchaseStore(String note, Long accountId, List<PurchaseOrder> orderList, String adminName, BigDecimal totalAmount, BigDecimal payAmount, BigDecimal debtAmount, Long state, Long storeId) {
        PurchaseStore purchaseStore = new PurchaseStore();
        purchaseStore.setAdminName(adminName);
        purchaseStore.setTotalAmount(totalAmount);
        purchaseStore.setNote(note);
        purchaseStore.setState(state);
        purchaseStore.setPayAmount(payAmount);
        purchaseStore.setDebtAmount(debtAmount);
        purchaseStore.setStorageId(storeId);
        purchaseStore.setAccountId(accountId);
        purchaseStore.setReceiptNumber(OrderNoUtil.getOrderNo());
        // 循环遍历orderList，设置purchaseStore的supplierName和receiptNumber属性
        for (PurchaseOrder order : orderList) {
            purchaseStore.setBillDate(order.getBillDate());
            purchaseStore.setSupplierName(order.getSupplierName());
            purchaseStore.setGoodsInfo(order.getGoodsInfo());
        }
        return purchaseStore;
    }

    /**
     * 修改入库
     *
     * @param purchaseStore 入库
     * @return 结果
     */
    @Override
    public int updatePurchaseStore(PurchaseStore purchaseStore) {
        return purchaseStoreMapper.updatePurchaseStore(purchaseStore);
    }

    /**
     * 批量删除入库
     *
     * @param ids 需要删除的入库主键
     * @return 结果
     */
    @Override
    public int deletePurchaseStoreByIds(Long[] ids) {
        return purchaseStoreMapper.deletePurchaseStoreByIds(ids);
    }

    /**
     * 删除入库信息
     *
     * @param id 入库主键
     * @return 结果
     */
    @Override
    public int deletePurchaseStoreById(Long id) {
        return purchaseStoreMapper.deletePurchaseStoreById(id);
    }
}
